public virtual class VirElement {
    //  Element(Element p, string n) {      parentNode = p;         nodeName = n;       } 
    public VirElement(string n) {  nodeName = n; } 
    public VirElement() {  }
    
    public VirElement(XmlStreamReader reader) {
    	
    }
    
    public void appendChild(VirElement e) {
        ((VirElement)e).ParentNode = this; 
        this.childNodes.add((VirElement)e);     
    }

    // some debugging help  
    public void dump() { dump('');}
    public void dump(string pre) { // just current node
        system.debug( pre + ' ' +this.nodeName + '->' + this.nodeValue + ' ' + this.attributes );  
    }
    public void dumpAll() { dumpAll('');    }
    public void dumpAll(string pre) { // node and all children
        system.debug( pre + this.nodeName + '->' + this.nodeValue + ' ' + this.attributes );  
        for (VirElement c: this.childNodes) { 
            c.dumpAll(pre+'   '); 
        }
    }
     public string toXmlString() {
        string ret = '<' + this.nodeName + ' ';
        for (  string a : attributes.keySet() ) {
            ret += a + '=\'' + attributes.get(a) + '\' ' ;
        }
        ret += '>';
        if (nodeValue == '' ) ret += '\n';
        for (VirElement c: this.childNodes) {  
            ret += c.toXmlString() ;//+ '\n'; 
        }   
        if (nodeValue != '' ) 
            ret += nodeValue;
        //else ret += '\n';
        return ret + '</' + this.nodeName + '>\n'; 
    }
    
    // utility methods
    public VirElement firstChild() { 
        if ( this.childNodes.size() == 0 ) return null; 
        return this.childNodes[0]; 
    }
    public VirElement ownerDocument() { 
        VirElement ret = this;  
        while( ret.parentNode != null) { ret = ret.parentNode; }            
        return ret; 
    } 
    
    // properties
    public VirElement parentNode = null; // only root has a null parent 
    public string nodeName = ''; 
    public string nodeValue = ''; 
    public List<VirElement> childNodes = new List<VirElement>();
    public map<String,String> attributes = new map<String,String>();
    
 }